package com.amigo.online.provider.adv.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import com.amigo.online.provider.adv.common.GlobalController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import com.amigo.online.common.param.result.AdvAreaInfo;
import com.amigo.online.common.param.result.AdvInfo;
import com.amigo.online.common.param.result.adv.ProvinceAndCity;
import com.amigo.online.provider.adv.common.ConstantValue;
import com.amigo.online.provider.adv.common.RwRedisService;
import com.amigo.online.provider.adv.entity.AdvArea;
import com.amigo.online.provider.adv.mapper.AdvAreaMapper;
import com.amigo.online.provider.adv.service.AdvHomeApplyService;
import com.amigo.online.provider.adv.service.AdvHomeLookRecordService;
import com.amigo.online.provider.adv.service.AdvNearbyApplyService;
import com.amigo.online.provider.adv.service.AdvNearbyLookRecordService;
import com.amigo.online.provider.adv.service.AdvRecommendApplyService;
import com.amigo.online.provider.adv.service.AdvRecommendLookRecordService;
import com.amigo.online.provider.adv.service.AdvService;
import com.amigo.online.provider.adv.service.AdvTantanApplyService;
import com.amigo.online.provider.adv.service.AdvTantanLookRecordService;
import com.amigo.online.provider.adv.service.AreaService;
import com.amigo.online.provider.adv.util.AdvBasicUtil;
import com.amigo.online.provider.adv.util.AgeEnum;
import com.amigo.online.provider.adv.util.LanguageEnum;


@Service
public class AdvServiceImpl implements AdvService {

    protected static Logger logger = LoggerFactory.getLogger(AdvServiceImpl.class);
    @Autowired
    protected RwRedisService rwRedisService;

    @Autowired
    AreaService areaService;

    @Autowired
    AdvHomeApplyService advHomeApplyService;

    @Autowired
    AdvNearbyApplyService advNearbyApplyService;

    @Autowired
    AdvRecommendApplyService advRecommendApplyService;

    @Autowired
    AdvTantanApplyService advTantanApplyService;

    @Autowired
    AdvAreaMapper advAreaMapper;

    @Autowired
    AdvTantanLookRecordService advTantanLookRecordService;

    @Autowired
    AdvNearbyLookRecordService advNearbyLookRecordService;

    @Autowired
    AdvRecommendLookRecordService advRecommendLookRecordService;

    @Autowired
    AdvHomeLookRecordService advHomeLookRecordService;

    @Override
    public List<AdvInfo> getAdvList(String city, Double lng, Double lat, String sex, Long age, String language,
                                    Double width, Double height, int number, int type) {
        logger.info("================arrive-here================");
        List<AdvInfo> result = new ArrayList<>();
        int ageType = 0;
        int sexType = 0;
        if (sex != null && age != null) {
            ageType = AgeEnum.getAgeType(age);
            if (ConstantValue.USER_WOMAN_SEX.equals(sex)) {
                sexType = 2;
            } else if (ConstantValue.USER_MAN_SEX.equals(sex)) {
                sexType = 1;
            }
        }

        Integer cityId = areaService.getPositionAreaIdByCityName(city, language);
        if (cityId == null) {
            cityId = 0;
        }
        double ratio = 1.778d;
        if (width != null && height != null) {
            ratio = width / height;
            BigDecimal bigDecimal = new BigDecimal(ratio);
            ratio = bigDecimal.setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue();
        }
        if (type == 1) {
            result = advHomeApplyService.listHomeAdvByAreaIdAndSexTypeAndAgeType(sexType, ageType, lng, lat, number, ratio);
        } else if (type == 2) {
            result = advRecommendApplyService.listHomeAdvByAreaIdAndSexTypeAndAgeType(sexType, ageType, lng, lat, cityId, number, ratio);
        } else if (type == 3) {
            result = advNearbyApplyService.listHomeAdvByAreaIdAndSexTypeAndAgeType(sexType, ageType, lng, lat, cityId, number, ratio);
        } else if (type == 4) {
            result = advTantanApplyService.listHomeAdvByAreaIdAndSexTypeAndAgeType(sexType, ageType, lng, lat, cityId, number, ratio);
        }
        if (result.size() != 0) {
            AdvService adSyncService = (AdvService) AopContext.currentProxy();
            adSyncService.recordlookInfo(result, type, age, sex, city, lng, lat);
        }
        return result;
    }

    @Async("asyncServiceExecutor")
    public void recordlookInfo(List<AdvInfo> result, int type, Long age, String sex, String cityId, Double lng, Double lat) {
        logger.info(Thread.currentThread().getName());
        for (AdvInfo temp : result) {
            if (type == 1) {
                advHomeLookRecordService.recordHomeAdvLooked(temp.getAdvId(), sex, age, lng, lat, cityId);
            } else if (type == 2) {
                advRecommendLookRecordService.recordRecommendAdvLooked(temp.getAdvId(), sex, age, lng, lat, cityId);
            } else if (type == 3) {
                advNearbyLookRecordService.recordNearbyAdvLooked(temp.getAdvId(), sex, age, lng, lat, cityId);
            } else if (type == 4) {
                advTantanLookRecordService.recordTantanAdvLooked(temp.getAdvId(), sex, age, lng, lat, cityId);
            }
        }

    }

    @Override
    @SuppressWarnings("unchecked")
    public Object getAreaInfoByCountryId(Long countryId, String language) {
        List<AdvArea> areaList = (List<AdvArea>) rwRedisService.get(ConstantValue.ADV_AREA_INFO + countryId);
        if (areaList == null) {
            areaList = advAreaMapper.getAreaList(countryId);
            rwRedisService.set(ConstantValue.ADV_AREA_INFO + countryId, areaList);
        }
        List<AdvAreaInfo> list = AdvBasicUtil.AdvAreaToAdvAreaInfo(areaList, LanguageEnum.getColumnName(language));
        return list;
    }

    @Override
    public ProvinceAndCity getProvinceAndCityByCityId(Long cityId, String column) {
        return advAreaMapper.getProvinceAndCityByCityId(cityId, column);
    }
}
